package com.randi.system.service.impl;

import com.randi.common.constant.CacheConstants;
import com.randi.common.core.domain.entity.SysMenu;
import com.randi.common.enums.ResultCode;
import com.randi.common.exception.ServiceException;
import com.randi.common.utils.SecurityUtils;
import com.randi.system.domain.params.SysMenuParam;
import com.randi.system.mapper.SysMenuMapper;
import com.randi.system.service.ISysMenuService;
import com.randi.common.utils.TreeUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author ziye
 */
@Service
@CacheConfig(cacheNames = "sys_menu")
public class SysMenuServiceImpl implements ISysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;

    /**
     * 查询业务列表
     *
     * @param sysMenuParam 检索参数
     * @return 业务集合
     */
    @Override
//    @Cacheable(keyGenerator = "baseKeyGenerator", unless = "#result == null or #result.isEmpty()")
    public List<SysMenu> selectSysMenuList(SysMenuParam sysMenuParam) {
        return sysMenuMapper.selectSysMenuList(sysMenuParam);
    }

    /**
     * 获取树形列表
     *
     * @param sysMenuParam 检索参数
     * @return sysMenus
     */
    @Override
    public List<SysMenu> selectSysMenuTreeList(SysMenuParam sysMenuParam) {
        List<SysMenu> sysMenuList = selectSysMenuList(sysMenuParam);

        if (sysMenuList.isEmpty()) {
            return Collections.emptyList();
        }

        return TreeUtils.buildTreeCustom(sysMenuList, SysMenu::getMenuId, SysMenu::getParentId, SysMenu::getChildren);
    }

    /**
     * 查看详情
     *
     * @return 业务集合
     */
    @Override
    @Cacheable(key = "#menuId", unless = "#result == null")
    public SysMenu selectSysMenuById(Long menuId) {
        return sysMenuMapper.selectSysMenuById(menuId);
    }

    /**
     * 插入数据
     *
     * @param sysMenu sysMenu
     * @return 结果
     */
    @Override
    @Caching(evict = {
            @CacheEvict(allEntries = true, beforeInvocation = true),
            @CacheEvict(value = CacheConstants.SYS_ROLE_MENU, allEntries = true, beforeInvocation = true)
    })
    public int insertSysMenu(SysMenu sysMenu) {
        Long parentId = sysMenu.getParentId();
        if (parentId != null && !parentId.equals(0L)) {
            SysMenu parentMenu = sysMenuMapper.selectSysMenuById(parentId);
            if (parentMenu == null || parentMenu.getDeleted() == 1) {
                throw new ServiceException(ResultCode.BUSINESS_INSERT_ERROR_SUP_MENU_NOT_EXIST);
            } else if (parentMenu.getStatus() == 1) {
                throw new ServiceException(ResultCode.BUSINESS_INSERT_ERROR_SUP_MENU_DISABLE);
            }
        }
        sysMenu.setMenuId(null);
        SecurityUtils.setInsertInfo(sysMenu);
        return sysMenuMapper.insert(sysMenu);
    }

    /**
     * 更新数据
     *
     * @param sysMenu SysMenu
     * @return 结果
     */
    @Override
    @Caching(evict = {
            @CacheEvict(allEntries = true, beforeInvocation = true),
            @CacheEvict(value = CacheConstants.SYS_ROLE_MENU, allEntries = true, beforeInvocation = true)
    })
    public int updateSysMenu(SysMenu sysMenu) {
        if (sysMenu.getMenuId() == null) {
            throw new ServiceException(ResultCode.PARAM_ERROR);
        }
        sysMenu.setParentId(null);
        sysMenu.setMenuType(null);
        SecurityUtils.setUpdateInfo(sysMenu);
        return sysMenuMapper.updateById(sysMenu);
    }

    /**
     * 批量删除数据
     *
     * @param menuIds menuIds
     * @return status
     */
    @Override
    @Caching(evict = {
            @CacheEvict(allEntries = true, beforeInvocation = true),
            @CacheEvict(value = CacheConstants.SYS_ROLE_MENU, allEntries = true, beforeInvocation = true)
    })
    public int deleteBatchSysMenu(List<Long> menuIds) {
        return sysMenuMapper.batchUpdateDeleted(menuIds);
    }

}
